package com.tanjun.common.utils;


import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.tanjun.common.exception.HttpException;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.codehaus.commons.nullanalysis.NotNull;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.util.Map;

/**
 * http请求工具
 */
@Slf4j
public class HttpRequestTools {

   /**
    * 发送get请求
    *
    * @param url           请求地址
    * @param data          请求数据
    * @param headers       请求头部信息
    * @param typeReference 返回类型
    * @param <T>           返回数据
    * @return 返回数据
    */

   public static <T> T get(@NotNull String url, @Nullable Object data, @Nullable Map<String, String> headers, @NotNull TypeReference<T> typeReference) {
      OkHttpClient client = new OkHttpClient();
      StringBuilder requestUrl = new StringBuilder(url);
      if (data!=null) {
         if (!url.contains("?")) {
            requestUrl.append("?");
         } else {
            requestUrl.append("&");
         }
        if(data!=null){
           Map<String,Object> json= JSON.parseObject(JSON.toJSONString(data),Map.class) ;
           json.forEach((k, v) -> {
              requestUrl.append(k + "=" + v + "&");
           });
           requestUrl.delete(requestUrl.lastIndexOf("&"), requestUrl.length());
        }
      }
      log.info("get 请求地址为:{}", requestUrl);
      Request.Builder requestBuilder = new Request.Builder()
              .url(requestUrl.toString())
              .get();

      if (!CollectionUtils.isEmpty(headers)) {
         headers.forEach((k, v) -> {
            requestBuilder.header(k, v);
         });
      }
      Response response = null;
      try {
         response = client.newCall(requestBuilder.build()).execute();
         if (response.isSuccessful()) { //请求成功
            String responseBody = response.body().string();
            log.info("get 请求成功，返回数据:{}", responseBody);
            return JSONObject.parseObject(responseBody, typeReference);
         } else {
            log.error("get 请求失败,code:{},body:{}", response.code(), response.body());
            throw new HttpException(response.code(), "get请求失败");
         }
      } catch (IOException e) {
         log.error("get 请求失败");
         throw new HttpException(-1, e.getMessage());
      }
   }


   /**
    * 发送post请求
    *
    * @param url           请求地址
    * @param data          请求数据
    * @param headers       请求头部信息
    * @param typeReference 返回类型
    * @param <T>           返回数据
    * @return 返回数据
    */

   public static <T> T postJson(@NotNull String url, @Nullable Object data, @Nullable Map<String, String> headers, @NotNull TypeReference<T> typeReference) {
      OkHttpClient client = new OkHttpClient();
      String strData = JSONObject.toJSONString(data);
      log.info("post 请求地址为:{},data:{}", url, strData);
      Request.Builder requestBuilder = new Request.Builder()
              .url(url)
              .post(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), strData));
      if (!CollectionUtils.isEmpty(headers)) {
         headers.forEach((k, v) -> {
            requestBuilder.header(k, v);
         });
      }
      Response response = null;
      try {
         response = client.newCall(requestBuilder.build()).execute();
         if (response.isSuccessful()) { //请求成功
            String responseBody = response.body().string();
            log.info("post 请求成功，返回数据:{}", responseBody);
            return JSONObject.parseObject(responseBody, typeReference);
         } else {
            log.error("post 请求失败,code:{},body:{}", response.code(), response.body());
            throw new HttpException(response.code(), "get请求失败");
         }
      } catch (IOException e) {
         log.error("post 请求失败");
         throw new HttpException(-1, e.getMessage());
      }
   }

   public static void main(String[] args) {
      String s = get("https://www.baidu.com/", null, null, new TypeReference<String>() {
      });
      System.out.println(s);
   }
}
